# -*- coding:cp437 -*-
# WARNIG : encodage pour Console DOS sous Windows uniquement !!!

# Insert Special
# based on : InsertNFO/Dolores
# (c) www.ctrl-pomme-reset.fr
# version 0.50 (13.09.2014)


import sys
import struct
import glob
import os.path

# interleaving !
#SectorList = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] #lent (1:1)
SectorList = [0,2,4,6,8,10,12,14,1,3,5,7,9,11,13,15] #moyen (2:1)
#SectorList = [0,3,6,9,12,15,1,4,7,10,13,2,5,8,11,14] #test1- bad
#SectorList = [0,3,6,9,12,15,2,5,8,11,14,1,4,7,10,13] #test2 (3:1) 
#SectorList = [0,3,6,9,12,15,2,5,1,4,7,10,13,8,11,14] #test3- bad
#SectorList = [0,3,6,9,12,15,2,5,14,11,8,13,10,7,4,1] #test4- bad
#SectorList = [0,4,8,12,15,3,7,11,14,2,6,10,13,1,5,9] #test5- bad
#SectorList = [0,3,6,9,12,15,2,5,13,8,11,14,1,4,7,10] #test6- bad
#SectorList = [0,3,6,9,12,15,2,5,1,4,7,8,10,11,13,14] #test7 (idem 3)
#SectorList = [0,3,6,9,12,15,2,5,1,7,10,13,4,8,11,14] #test8 - bad
#SectorList = [0,3,6,9,12,14,1,4,7,10,13,15,2,5,8,11] #test9 - bof

# routines

def WriteFRA(modDSK, nameBinary1, nameBinary2, track, sector): 
    fbin1 = open(nameBinary1,"rb")
    load1 = fbin1.read()                            # lecture du fichier binaire1
    lenBin1 = len(load1)                            # on r‚cupŠre la taille du binaire1
    modBin1 = bytearray(load1)                      # cr‚ation array avec le bin1   

    fbin2 = open(nameBinary2,"rb")
    load2 = fbin2.read()                            # lecture du fichier binaire2
    lenBin2 = len(load2)                            # on r‚cupŠre la taille du binaire2
    modBin2 = bytearray(load2)                      # cr‚ation array avec le bin2

    s = SectorList[sector]
    offset = track*0x1000+s*0x100              # calcul offset dans le fichier DSK pour l'‚criture
                                                    # correspondant … track/sector
    
    j = 0
    k = 0
    while j<lenBin1:
        modifiedDSK[offset+k] = modBin1[j]
        j +=1
        k +=1

    j = 0                                           # nouvelle boucle pour deuxiŠme bin

    while j<lenBin2:
        modifiedDSK[offset+k] = modBin2[j]
        j +=1
        k +=1
        
    modifiedDSK[offset+k] = 0                       # octet de fin de d‚compression : 00
    k +=1                                           # calcul k final pour affichage
    
    print 'Injection de {} et {} ({} octets)'.format(nameBinary1,nameBinary2,k),
    print "T{:02X}/S{:02X}".format(track,s)
    
    # fin - nettoyage / fermeture fichier
    fbin1.close()                       # fermeture fichier binaire1
    fbin2.close()                       # fermeture fichier binaire2

    return


if __name__ == '__main__':

    print
    print("Insert Special v0.50 - 2014")
    print

    if len(sys.argv) < 4:
        nameDSK = raw_input("Nom du de l'image disk : ")
        trackd = int(raw_input("Piste de d‚part (Hexa) : "),16)
        sectord = int(raw_input("Secteur de d‚part (Hexa) : "),16)
    else:    
        nameDSK = sys.argv[1]
        trackd = int(sys.argv[2],16)
        sectord = int(sys.argv[3],16)

    fDSK = open(nameDSK,"rb+")                  # ouverture fichier DSK (lecture + modification)
    record = fDSK.read()                        # lecture complŠte
    if len(record) != 143360:                   # v‚rification taille standard d'un fichier DSK
        print ("erreur avec le fichier DSK")
    else :
        bufDSK = struct.Struct("<143360B")      # structure fichier DSK (143360 x 1 byte)
        outDSK = bufDSK.unpack(record)          # on unpack le fichier DSK vers la structure d‚finie
        modifiedDSK = bytearray(outDSK)         # on cr‚e une bytearray … partir du contenu pour pouvoir la modifier

    track = trackd
    sector = sectord
    
    l = glob.glob('*.fra')                      # liste tous les fichiers .fra du rep
    # boucle principale
    sens = 0                                    # sens ascendant pour commencer !
    for i in range(0,len(l),2):                                     # boucle traitement liste
        (filepath1,filename1)=os.path.split(l[i])                   # d‚coupe path+filename
        (filepath2,filename2)=os.path.split(l[i+1]) 
        WriteFRA(modifiedDSK,filename1,filename2,track,sector)
        # calcul prochain track/sector
        if sens == 0:                           # sens ascendant !
            sector +=1                          # secteur suivant
            if sector>0x7:                      # en bout de piste (7 pour le sens ascendant) ?
                sector = 0                      # secteur remis … 0
                track +=1                       # ... et piste suivante
                if track > 0x22:                # bout du disk ? on redescent !
                    sens = 1                    # sens descendant
                    track = 0x22                # on repart de la piste $22
                    sector = 8                  # ... secteur 8
                    continue                    # prochaine it‚ration boucle !

        if sens == 1:                           # sens descendant
            sector +=1                          # secteur suivant
            if sector>0x0F:                     # en bout de piste (0F pour le sens descendant) ?
                sector = 8                      # secteur remis … 8
                track -=1                       # ... et piste pr‚c‚dente
                if track < trackd:              # t < track de d‚part ? on a fini quoiqu'il arrive !
                    break                       # on sort de la boucle for

    record = bufDSK.pack(*modifiedDSK)          # on repack la liste modif‚e vers la structure
    fDSK.seek(0)			        # on remet … zero le file pointer (pour tout r‚‚crire)
    fDSK.write(record)                   	# ecriture vers fichier sortie de la structure
    print
    print "-> fichier",nameDSK,"modifi‚ et sauv‚"

    fDSK.close()                                # fermeture fichier DSK
